package cn.teduo;


import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class dou29 {
    public static void main(String[] args) throws Exception {
//   getFields();
        eat();

    }
    @Test
    public static void getFields() throws Exception {
       Class<?> clazz = dou28.class; //获取类字节码对象
      Field field = clazz.getDeclaredField("aage");//获取封装属性
        System.out.println(field.getType().getName());//获取类属性
        System.out.println(field.getType());//获取类
        Method[] ms = clazz.getMethods();//获取构造方法 遍历
        for (Method ss:ms){
            System.out.println(ss.getName());//打印构造方法名
            Class<?>[] pt = ss.getParameterTypes();//获取构造方法参数，数组
            System.out.println(Arrays.toString(pt));//打印参数类型
            //设置封装属性
            Object obj = clazz.newInstance();
            //暴力反射！需要设置私有可见
            field.setAccessible(true);
            //给指定对象设置值
             field.set(obj,123);
            //获取私有属性的值
            System.out.println(field.get(obj));
        }
    }
    //2,暴力反射获取私有方法2
    @Test
    public static void eat() throws Exception {
        Class<?> c = dou28.class;
        //getDeclaredMethod(m,x.y.z...)
        //m:要获取的方法名
        //x,y,z...可变参数，是这个方法的参数类型，要注意加.class
        Method method = c.getDeclaredMethod("save",String.class,Integer.class);
        Object obj = c.newInstance();//没有对象就通过反射的方式创建对象
        //暴力反射！想要执行私有方法，也需要设置私有可见,
        method.setAccessible(true);
        //通过反射技术invoke(),执行目标对象obj的目标方法method[save()]
        //save()呗调用时传入的参数时100，海绵宝宝
        method.invoke(obj,"海绵宝宝",18);//invoke(o,x,y,z...
        //o :要执行的是哪个对象的方法
        //x,y,z....：执行这个方法【method对象代表的之前获取到save()】时需要传入的参数
        // )
    }
}
